package avriServer.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Calendar;

import avriServer.server.AvriServer;


public abstract class Client {
	protected Socket socket ;
	protected PrintStream printStream ;
	protected BufferedReader bufferedReader;
	public Client () {		
	}
	
	public Client (Socket _s) {
		this.socket = _s ;		
	}
	public Client(Socket _s, PrintStream _printStream, BufferedReader _bufferedReader) {
		this.printStream = _printStream ;
		this.socket = _s ;
		this.bufferedReader = _bufferedReader ;
	}
	/**
	 * Close all the connections
	 */
	public void close (){
		try {
			this.printStream.close();
		} catch (Exception e) {
		}
		try {
			this.socket.close();
		} catch (Exception e) {
		}
		try {
			this.bufferedReader.close() ;
		} catch (Exception e) {
		}
	}
	
	public Socket getSocket () {
		return this.socket;
	}
	
	public BufferedReader getBufferedReader () {
		return this.bufferedReader;
	}
	
	public PrintStream getPrintStream () {
		return this.printStream;
	}
	
	/**
	 * Send the cometHeader to the browser.
	 * Specific header is sent for each browser.
	 */
	public void sendCometHeader (int _cometType) {
		Calendar c = Calendar.getInstance();
		String date = c.get(Calendar.DAY_OF_MONTH) + "/" + c.get(Calendar.MONTH) + "/" + c.get(Calendar.YEAR);
		try {
			this.printStream.print("HTTP/1.1 200 OK");
			this.printStream.write(AvriServer.EOL);
			this.printStream.print("Date: "+date);
			this.printStream.write(AvriServer.EOL);
			this.printStream.print("Server: DWR-Reverse-Ajax Comet AvriChatServer");
			this.printStream.write(AvriServer.EOL);
			
			//Ie specific header
			if(AvriServer.COMET_TYPE.get("Trident") == _cometType)
				this.printStream.print("Content-Type: text/html; charset=utf-8");
			//gecko && webkit specific header
			else if(AvriServer.COMET_TYPE.get("Webkit") == _cometType)
				this.printStream.print("Content-Type: multipart/x-mixed-replace;boundary=XXoXoX;");
			//presto engine
			else if(AvriServer.COMET_TYPE.get("Presto") == _cometType)
				this.printStream.print("Content-Type: application/x-dom-event-stream");
			
			//this.pw.print("Connection: Connection");
			//this.pw.write(Server.EOL);
			this.printStream.print("Cache-Control: no-store, no-cache");
			this.printStream.write(AvriServer.EOL);
			this.printStream.write(AvriServer.EOL);
			//Avast web shield specific debug, should be improve
			//TODO : improve the sleep : only on retry.
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			this.printStream.write(AvriServer.EOL);
		} catch (IOException e) {
			e.printStackTrace();
		}
		if(AvriServer.COMET_TYPE.get("Trident") == _cometType) {
			this.printStream.print("<span></span><span></span><span></span><span></span><span></span><span></span><span></span>");
		}
		this.printStream.flush();
	}

	/**
	 * Push a data to the browser. The data will be catch by the javascript object.
	 * @param _stringToBePush
	 */
	protected synchronized void push (String _stringToBePush, int _cometType, String _cometName) {
		if (_stringToBePush != null && _stringToBePush.length()>0) {
			_stringToBePush = "["+_stringToBePush+"]";
			System.out.println("Data push: "+_stringToBePush);
			try {
				if(AvriServer.COMET_TYPE.get("Webkit") == _cometType) {
					this.printStream.print("Content-Type: text/json\r\n\r\n"+_stringToBePush+"\r\n\r\n--XXoXoX\r\n");
				}
				else if(AvriServer.COMET_TYPE.get("Presto") == _cometType) {
					this.printStream.print("Event: "+_cometName+"\ndata: "+_stringToBePush+"\n\n");
				}
				else if(AvriServer.COMET_TYPE.get("Trident") == _cometType) {
					this.printStream.print("<script type=\"text/javascript\">parent._cometObject.fireEvent('dataPushed', "+_stringToBePush+")</script>");
					this.printStream.write(AvriServer.EOL);
				}
				else if(AvriServer.COMET_TYPE.get("Other") == _cometType) {
					//this.printStream.print("<script type=\"text/javascript\">alert('toto');</script>");
					this.printStream.print(_stringToBePush);
					this.printStream.write(AvriServer.EOL);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			this.printStream.flush();
		}
	}
}
